package main

import (
	"fmt"
	sentinel "github.com/alibaba/sentinel-golang/api"
	"github.com/alibaba/sentinel-golang/core/base"
	"github.com/alibaba/sentinel-golang/core/flow"
	"log"
	"math/rand"
	"time"
)

func main() {
	// 务必先进行初始化
	err := sentinel.InitDefault()
	if err != nil {
		log.Fatalf(err.Error())
	}
	// 配置一条限流规则
	_, err = flow.LoadRules([]*flow.Rule{
		{
			Resource:               "some-test", //熔断器规则生效的埋点资源的名称
			TokenCalculateStrategy: flow.Direct, //Direct表示直接使用字段
			ControlBehavior:        flow.Reject, //Reject表示超过阈值直接拒绝
			Threshold:              1000,        //QPS流控阈值1000/WarmUpPeriodSec
			StatIntervalInMs:       1000,        //QPS时间长度1s
			//WarmUpPeriodSec: 1, //预热的时间长度
		},
	})
	if err != nil {
		log.Fatalf("配置规则出错：", err.Error())
	}
	//计数
	var (
		//统计 总共有多少条记录
		globalTotal int
		//统计 pass了多少条记录
		passTotal int
		//统计 通过了多少条记录
		blockTotal int
	)
	//用来阻塞主线程
	ch := make(chan struct{})
	//模拟流量并发
	for i := 0; i < 100; i++ {
		go func() {
			for {
				globalTotal++
				e, b := sentinel.Entry("some-test", sentinel.WithTrafficType(base.Inbound))
				if b != nil {
					blockTotal++
					time.Sleep(time.Millisecond * (time.Duration(rand.Uint64() % 10)))
				} else {
					passTotal++
					time.Sleep(time.Millisecond * (time.Duration(rand.Uint64() % 10)))
					e.Exit()
				}
			}
		}()
	}
	//每秒记录上述数据（1s内）
	go func() {
		var (
			temTotal int
			temPass  int
			temBlock int
		)
		for {

			oneTotal := globalTotal - temTotal
			temTotal = globalTotal

			onePass := passTotal - temPass
			temPass = passTotal

			oneBlock := blockTotal - temBlock
			temBlock = blockTotal
			time.Sleep(time.Second)
			fmt.Printf("Total:%d,Pass:%d,Block:%d\n", oneTotal, onePass, oneBlock)
		}
	}()

	<-ch
}
